package cn.iocoder.yudao.module.promotion.redpacket.service.core;

import cn.iocoder.yudao.framework.business.basic.service.impl.AbstractService;
import cn.iocoder.yudao.module.api.promotion.redpacket.vo.RedPacketAmountVO;
import cn.iocoder.yudao.module.api.trade.scan.dto.ScanOrderDTO;
import cn.iocoder.yudao.module.promotion.redpacket.convert.RedPacketUsedConvert;
import cn.iocoder.yudao.module.promotion.redpacket.dao.RedPacketUsedMapper;
import cn.iocoder.yudao.module.promotion.redpacket.mq.RedPacketProducer;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.po.RedPacketUsed;
import cn.iocoder.yudao.module.promotion.redpacket.pojo.vo.RedPacketUsedVO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;

/**
 * <pre>
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * 服务
 * OOoO0OOoO0OOOooo0oOOOO0OOOOO0oooOO0ooOOO0Ooooo0OOOOo0ooooO0OOooo0Ooooo0OOOOO
 * </pre>
 *
 * @author 山野羡民（1032694760@qq.com）
 * @since 2025/07/26
 */
@Slf4j
@Service
public class CoreRedPacketUsedService extends AbstractService<RedPacketUsed, RedPacketUsedVO> {
    @Resource
    private RedPacketUsedMapper redPacketUsedMapper;

    @Resource
    private RedPacketProducer redPacketProducer;

    @Resource
    @Lazy // 延迟加载，避免循环依赖
    private CoreRedPacketRecordService coreRedPacketRecordService;

    @Override
    public RedPacketUsedMapper getInjectedMapper() {
        return redPacketUsedMapper;
    }

    @Override
    public RedPacketUsedVO convertToViewObject(RedPacketUsed entity) {
        return RedPacketUsedConvert.INSTANCE.toViewObject(entity);
    }

    public void useRedPacketIfNecessary(ScanOrderDTO order) {
        if (order.getRedpacketDeductPrice() <= 0) {
            log.debug("用户[{}]在店铺[{}]下单({})没有使用红包抵扣", order.getUserId(), order.getShopId(), order.getTradeNo());
            return;
        }
        // 查询用户的已生效、未过期且未使用的红包
        RedPacketAmountVO redPacketAmount = coreRedPacketRecordService.getRedPacketAmount(order.getUserId(), order.getShopId());
        if (redPacketAmount.getUnusedAmount() < order.getRedpacketDeductPrice()) {
            log.warn("用户[{}]在店铺[{}]下单({})红包金额不足，需抵扣金额({})，剩余红包金额[{}]，这种情况理论上不会出现，因为选择红包抵扣之前已经确保用户红包可用且够用", order.getUserId(), order.getShopId(), order.getTradeNo(), order.getRedpacketDeductPrice(), redPacketAmount.getUnusedAmount());
            return;
        }
        // 增加红包抵扣记录，注意幂等性
        if (redPacketUsedMapper.insertIfNecessary(order)) {
            redPacketProducer.sendRedPacketUsageMessage(order.getShopId(), order.getUserId(), order.getRedpacketDeductPrice(), order.getTradeNo());
        }
    }

    public int sumUsedAmount(Long userId, @Nullable Long shopId) {
        return redPacketUsedMapper.sumUsedAmount(userId, shopId);
    }

}
